<template>
  <v-stepper v-model="step">
    <v-stepper-header class="mt-2">
      <v-stepper-step :complete="step > 1" step="1">基本信息</v-stepper-step>

      <v-divider></v-divider>

      <v-stepper-step :complete="step > 2" step="2">商品描述</v-stepper-step>

      <v-divider></v-divider>

      <v-stepper-step :complete="step > 3" step="3">规格参数</v-stepper-step>

      <v-divider></v-divider>

      <v-stepper-step step="4">SKU属性</v-stepper-step>
    </v-stepper-header>

    <v-stepper-items>
      <v-stepper-content step="1" style="height: 480px">
        <v-form v-model="valid"  ref="basic">
          <v-layout class="justify-center">
            <v-flex xs12>
                <v-layout row>
                  <v-flex xs5>
                    <v-cascader
                      url="/item/category/list"
                      showAllLevels
                      required
                      v-model="goods.categories"
                      label="请选择商品分类"/>
                  </v-flex>
                  <v-spacer></v-spacer>
                  <v-flex xs5>
                    <!--品牌-->
                    <v-select
                      :items="brandOptions"
                      item-text="name"
                      item-value="id"
                      label="所属品牌"
                      required
                      v-model="goods.brandId"
                      autocomplete
                      clearable
                      dense chips
                      :rules="[v => !!v || '品牌不能为空']"
                    />
                  </v-flex>
                </v-layout>
            </v-flex>
          </v-layout>
          <v-text-field label="商品标题" v-model="goods.title" :counter="200" :rules="[v => !!v || '品牌名称不能为空']" required />
          <v-text-field label="商品卖点" v-model="goods.subTitle" :counter="200"/>
          <v-text-field label="包装清单" v-model="goods.spuDetail.packingList" :counter="500" multi-line :rows="3"/>
          <v-text-field label="售后服务" v-model="goods.spuDetail.afterService" :counter="500" multi-line :rows="3"/>
        </v-form>
      </v-stepper-content>

      <v-stepper-content step="2" >
        <!--<quill-editor style="height: 430px" v-model="goods.spuDetail.description" :options="editorOption"/>-->
        <v-editor  v-model="goods.spuDetail.description" upload-url="/upload/image" fileName="file"/>
        <v-divider></v-divider>
      </v-stepper-content>

      <v-stepper-content step="3">
        <v-flex class="xs10 mx-auto px-3">
            <v-card v-for="spec in specifications" :key="spec.group" class="my-2">
              <v-card-title class="subheading"><h4>{{spec.group}}</h4></v-card-title>
                <v-divider></v-divider>
                <v-card-text v-for="param in spec.params" :key="param.key" v-if="param.global" class="px-5">
                  <!--判断是否有可选项，如果没有，则显示文本框。还要判断是否是数值类型，如果是则把unit显示到后缀-->
                  <v-text-field v-if="param.options.length <= 0" :label="param.k" v-model="param.v" :suffix="param.unit || ''"></v-text-field>
                  <!--否则，显示下拉选项-->
                  <v-select v-else :label="param.k" v-model="param.v" :items="param.options"/>
                </v-card-text>
            </v-card>
        </v-flex>
      </v-stepper-content>
      <v-stepper-content step="4">
        <v-card v-for="spec in specialSpecs" :key="spec.k">
          <v-card-title v-if="spec.options.length <= 0" class="subheading">
            <h4 class="xs3">{{spec.k}}</h4>
            <v-spacer></v-spacer>
            <!--
                如何控制文本框的增加与删除
                1.借助selected属性，因为它是一个数组，所以可以把文本框的个数与数组的长度绑定
                2.获取selected的长度，点击增加，则把selected.length++复制给count
                3.然后用v-for遍历count,显示出对应个数的文本框，然后文本框绑定对应的selected数组下标,因为v-for遍历是从1开始的，
                  所以count+1，然后文本框与数组下标绑定的时候下标为i-1
                4.删除，是把文本框对应的数组下标中所包含的内容从数组中移除，使用splice函数，从i-1开始
            -->
            <v-btn flat icon color="primary" @click="count=spec.selected.length++">
              <v-icon>add</v-icon>
            </v-btn>
          </v-card-title>
          <v-card-title v-else class="subheading">
            <h4>{{spec.k}}</h4>
          </v-card-title>
          <v-card-text v-if="spec.options.length <= 0" class="px-5">
            <!--当可选属性options的长度为0时，进行渲染，说明此时是对特有属性的渲染-->
            <div v-for="i in count+1" :key="i">
              <v-layout row>
                <v-text-field :label="'输入新的'+spec.k" v-model="spec.selected[i-1]"></v-text-field>
                <!--当数组的长度为0时，说明是第一次渲染，所以此时禁用删除按钮；当长度为1时，说明不是第一次渲染，可能是增加完进行删除后的结果，所以此时也要禁用删除按钮-->
                <v-btn :disabled="spec.selected.length === 1 || spec.selected.length === 0" flat icon color="error" @click="spec.selected.splice(i-1,1),count=spec.selected.length-1">
                  <v-icon>delete</v-icon>
                </v-btn>
              </v-layout>
            </div>
          </v-card-text>
          <v-card-text v-else class="container fluid grid-list-xs">
              <v-layout row wrap class="px-5">
                <v-checkbox color="primary" v-for="p in spec.options" :key="p" class="flex xs3" :label="p" v-model="spec.selected" :value="p">
                </v-checkbox>
              </v-layout>
          </v-card-text>
        </v-card>
        <v-divider></v-divider>
        <v-card>
          <v-card-title class="subheading"><h4>SKU列表</h4></v-card-title>
          <v-card-text v-if="skusLength > 0">
            <v-data-table :items="skus" :headers="headers" hide-actions item-key="indexes" class="elevation-4">
              <!--数据列表-->
              <template slot="items" slot-scope="props">
                <tr @click="props.expanded = !props.expanded">
                  <td class="text-xs-center" v-for="(v,k) in props.item" :key="k"
                      v-if="!['id','price','stock','enable','indexes','images'].includes(k)"
                  >{{v}}
                  </td>
                  <td   class="text-xs-center">
                    <v-text-field single-line label="d" v-model="props.item.price"
                                  :rules="[val => /^([1-9]\d*)\.?(\d{0,2})$/.test(val) || '价格格式错误']"/>
                  </td>
                  <td  class="text-xs-center">
                    <v-text-field single-line label="0" v-model="props.item.stock"
                                  :rules="[val => /^[1-9]\d*$/.test(val) || '库存必须是整数']"/>
                  </td>
                  <!--
                    坑：如果不添加判断为什么点击checkbox没有反应？  计算属性
                  -->
                  <td   class="text-xs-center">
                    <v-checkbox color="primary" v-model="props.item.enable"/>
                  </td>
                </tr>
              </template>
              <!--点击表格后展开-->
              <template v-if="props.item.enable" class="px-4" slot="expand" slot-scope="props">
                <v-card flat>
                  <v-card-title><h4>上传图片</h4></v-card-title>
                  <v-card-text>
                    <v-upload ref="image_url"
                              v-model="props.item.images"
                              url="/upload/image"
                              :multiple="true"
                              :pic-width="250"
                              :pic-height="250"
                    />
                  </v-card-text>
                </v-card>
              </template>
            </v-data-table>
          </v-card-text>
          <v-card-text v-else>
            <v-alert :value="true" color="warning" icon="warning">
              请选择商品属性
            </v-alert>
          </v-card-text>
        </v-card>
        <v-layout row>
          <v-spacer></v-spacer>
            <v-btn
              :loading="loading3"
              :disabled="loading3"
              color="blue-grey"
              class="white--text mt-5"
              @click.native="loader = 'loading3'"
              @click="submit"
            >
             保存商品信息
              <v-icon right dark>cloud_upload</v-icon>
            </v-btn>
        </v-layout>
      </v-stepper-content>
    </v-stepper-items>
  </v-stepper>
</template>

<script>
  import 'quill/dist/quill.core.css'
  import 'quill/dist/quill.snow.css'
  import 'quill/dist/quill.bubble.css'

  import {quillEditor} from 'vue-quill-editor'
    export default {
      name: "MyGoodsForm",
      data () {
        return {
          editorOption: {// 富文本编辑器配置
            placeholder: '编写商品描述信息，让客户了解你的商品'
          },
          valid: false, //数据校验
          goods:{
            categories:null,  //商品3级分类数组信息
            brandId:0, //品牌id信息
            title:'', //标题
            subTitle:'', //子标题,卖点
            spuDetail:{
              packingList:'', //包装列表
              afterService:'', //售后服务
              description: '', //商品描述
              specTemplate: '',// sku属性模板的字符串格式
              specifications:[],
            }
          },
          brandOptions:[], //品牌列表
          specifications:[],//公共规格参数模板
          specialSpecs:[], //特有规格参数模板
          count:0, //文本框的数量
          loading3:false,
          loader: null,
          //isEdit:false,
          oldData:[],
          allSpecs:[]
        }
      },
      props:{
        oldGoods:{
          type: Object
        },
        step:{
          type:Number,
          default: 1
        },
        show:{
          type:Boolean,
          default: false
        },
        isEdit:{
          type:Boolean,
          default: false
        }
      },
      watch:{
        'goods.categories':{
          deep:true,
          handler(val){
            //判断商品分类是否存在，存在才查询
            if(val && val.length > 0) {
              //根据分类查询品牌
              this.$http.get("/item/brand/cid/" + this.goods.categories[2].id).then(({data}) => {
                this.brandOptions = data;
              }).catch();
              //根据分类查询规格参数模板
              this.$http.get("/item/spec/" + this.goods.categories[2].id).then(({data}) => {
                //保存全部规格，新增商品时使用
                this.allSpecs = data;
                this.dataProces(data);
                //过滤出SKU属性，同时将SPU中的特有属性置空
                //如果是新增，那么调用dataProces对数据进行处理，否则调用editDtaProces对数据进行处理。
                if (this.isEdit) {
                  this.editDataProces(this.oldData);
                }
              }).catch()
            }
          }
        },
        loader () {
          const l = this.loader;
          this[l] = !this[l];

          setTimeout(() => (this[l] = false), 2000)

          this.loader = null
        },
        oldGoods:{
          deep: true,
          handler(val){
            if (val !== null && val.spuDetail !== null){
              this.goods = Object.deepCopy(val);
              this.isEdit = true;
              this.oldData = val.spuDetail.specifications;
            }else {
              this.clear();
            }
          }
        },
        show:{
          deep:true,
          handler(val){
            if (val === true && this.isEdit === false){
              this.clear();
              //步骤线初始化
              this.$emit('initStep');
            }else if (val === true && this.isEdit === true){
              //步骤线初始化
              this.$emit('initStep');
            }
          }
        }
      },
      components: {
        quillEditor
      },
      computed:{
        skus(){
            //1.过滤掉用户没有填写数据的规格参数
            const arr = this.specialSpecs.filter(s => s.selected.length > 0);
            //console.log(arr);
          /**
           * 如果是进行修改时，需要根据options的长度来判断文本框的个数
           */
           for (let i = 0;i < arr.length;i++){
              if (arr[i].options.length === 0){
                this.count = arr[i].selected.length-1;
              }
           }
            //2.通过reduce进行累加笛卡儿积
            //3.数据优化：价格、库存、是否启用、商品的图片、分类组合索引
            return arr.reduce((last, spec, index) => {
              const result = [];
              last.forEach(o => {
                for (let i = 0; i < spec.selected.length; i++) {
                  const option = spec.selected[i];
                  const obj = {};
                  Object.assign(obj, o);
                  obj[spec.k] = option;
                  //拼接当前这个特有属性的索引
                  obj.indexes = (o.indexes || '') + '_' + i;
                  if (index === arr.length - 1) {
                    //如果发现是最后一组，则添加价格、库存等字段
                    const {indexes, ...rest} = obj;
                    if (this.isEdit){
                      const skuList = this.goods.skusList;
                      for (let i = 0 ; i < skuList.length ; i++){
                          if (Object.is(JSON.stringify(rest),skuList[i].ownSpec)){

                            let tempImage = [];
                            if (skuList[i].images.search(',') !== -1){
                              tempImage = skuList[i].images.split(',');
                            }else {
                              tempImage.push(skuList[i].images);
                            }
                            Object.assign(obj, {price: this.$format(skuList[i].price), stock: skuList[i].stock, enable:skuList[i].enable , images: tempImage});
                            break;
                          }else {
                            //如果已经启用，回显源数据，否则，正常构造
                            Object.assign(obj, {price: 0, stock: 0, enable: false, images: []});
                          }
                        }
                    }
                    else {
                      Object.assign(obj, {price: 0, stock: 0, enable: false, images: []});
                    }
                    //去掉索引字符串开头的下划线
                    obj.indexes = obj.indexes.substring(1);
                  }
                  result.push(obj);
                }
              });
              return result;
            }, [{}]);
        },
        headers(){
          if(this.skus.length <= 0){
            return [];
          }
          const headers = [];
          Object.keys(this.skus[0]).forEach(k =>{
             let value = k;
             if (k === 'price'){
               k = "价格";
             }else if(k === 'stock'){
               k = "库存";
             }else if(k === 'enable'){
               k = "是否启用"
             }else if(k === 'indexes' || k === 'images'){
               return ;
             }
             headers.push({
               text:k,
               align:"center",
               sortable:false,
               value
             })
          });
          return headers;
        },
        skusLength(){
          if (Object.values(this.skus[0]).length > this.specialSpecs.length+4)
            return this.skus.length;
          else return 0;
        }
      },
      methods:{
        //新增商品时数据处理
        dataProces(temp){
          let commonTemplate = [];
          let specialTemplate = [];
          let count = 0;
          temp.forEach(({params}) => {
            params.forEach(({k, options, global}) => {
              if (!global) {
                specialTemplate.push({
                  k, options, selected: []
                })
              }
            })
          });

          for (let i=0;i<temp.length;i++){
            if (temp[i].params.length > 0){
              let temp2 = temp[i].params;
              let param = [];
              for (let j = 0;j < temp2.length; j++){
                if (temp2[j].global){
                  param.push(temp2[j]);
                }
              }
              if (count !== temp2.length && param.length !== 0) {
                commonTemplate.push({
                  group: temp[i].group,
                  params: param,
                });
              }
            }
          }

          this.specialSpecs = specialTemplate;
          this.specifications = commonTemplate;
        },
        //修改商品时数据处理
        editDataProces(temp){
          /**
           * 特殊属性数据处理
           * 将用户选择的相关信息显示到对应区域
           * @type {Array}
           */
          //console.log(temp);
          const editSpecialTemplate = [];
            temp.forEach(({params}) => {
              params.forEach(({k, v,options,global}) => {
                //要进行测试，特有属性不是数组！！！！！！
                if (!global) {
                  if (options === null) {
                    editSpecialTemplate.push({
                      k, v
                    })
                  }
                  else {
                    editSpecialTemplate.push({
                      k, selected:options
                    })
                  }
                }
              })
            });
            for (let i = 0;i < editSpecialTemplate.length;i++){
              for (let j = 0;j < this.specialSpecs.length;j++){
                if (editSpecialTemplate[i].k === this.specialSpecs[j].k){
                  this.specialSpecs[i].selected = editSpecialTemplate[j].selected;
                }
              }
            }
          const editCommonTemplate = [];
          let count = 0;
          for (let i=0;i<temp.length;i++){
            if (temp[i].params.length > 0){
              let temp2 = temp[i].params;
              let param = [];
              for (let j = 0;j < temp2.length; j++){
                if (temp2[j].global){
                  param.push(temp2[j]);
                }
              }
              if (count !== temp2.length && param.length !== 0) {
                editCommonTemplate.push({
                  group: temp[i].group,
                  params: param,
                });
              }
            }
          }

          this.specifications.forEach(({group,params}) => {
              editCommonTemplate.forEach(s => {
                if (s.group === group){
                  s.params.forEach(({k,v}) => {
                    params.forEach(t => {
                      if (t.k === k){
                        t.v = v;
                      }
                    })
                  })
                }
              })
          })
        },
        submit(){
          //1.先处理goods，用结构表达式接收，除了categories外，都接收到goodsParams中
          const {categories: [{id:cid1},{id:cid2},{id:cid3}], ...goodsParams} = this.goods;
          //2.处理全部规格参数
          //目前specifications中只有公共属性的值，要把特有属性的值加上，一起存入数据库

          this.allSpecs.forEach(({group,params}) => {
            const special = this.specialSpecs;
            params.forEach(s => {
              if (!s.global){
                //如果是特殊属性，那么从specialSpecs中获取selected的值赋值给option
                special.forEach(t => {
                  if (t.k === s.k){
                    s.options = t.selected
                  }
                })
              }
            })
          });
          //去掉公共属性中的options
          const specs = this.allSpecs.map(({group,params}) => {
            const newParams = params.map(s => {
              if (s.global) {
                let {options, ...rest} = s;
                return rest;
              }else {
                return s;
              }
            });
            return {group,params:newParams}
          });
          //3.处理特有规格参数模板
          const specTemplate = {};
          this.specialSpecs.forEach(({k,selected}) => {
            specTemplate[k] = selected;
          });
          //4.处理sku
          // console.log("修改");
          // console.log(this.skus);
          const skus = this.skus.filter(s => s.enable).map(({price,stock,enable,images,indexes, ...rest}) => {
            //标题，在spu的title基础上，拼接特有规格属性值(内存、机身存储、机身颜色)
            const title = goodsParams.title+" "+Object.values(rest).join(" ");
            return {
              price: this.$format(price+""),enable,indexes,title, //基本属性
              stock: stock,
              images: images && images.length > 0 ? images.join(",") : "", //图片
              ownSpec:JSON.stringify(rest),  //特有规格参数
            }
          });
          Object.assign(goodsParams,{
            cid1,cid2,cid3, //商品分类
            skus,
          });
          goodsParams.spuDetail.specifications = JSON.stringify(specs);
          goodsParams.spuDetail.specTemplate = JSON.stringify(specTemplate);

          this.verify().then(() => {
            this.$http({
              url:"/item/goods",
              method: this.isEdit ? 'put':'post',
              data:goodsParams
            }).then(() => {
              //成功，关闭窗口
              setTimeout(() =>{
                this.$emit('close');
                this.$message.success("保存成功！");
                this.clear();
              },2000);
            }).catch(() => {
              this.$message.error("保存失败！");
            });
          }).catch(() => {
            this.$router.push("/login");
          });
        },
        clear(){
          //清空表单
          //this.oldGoods = {};
          this.goods.categories = [];
          this.goods.brandId = 0;
          this.goods.title = '';
          this.goods.subTitle = '';
          this.goods.spuDetail.packingList = '';
          this.goods.spuDetail.afterService = '';
          this.goods.spuDetail.description = '';
          this.brandOptions = [];//品牌列表
          this.specifications = [];//规格参数模板
          this.specialSpecs = []; //特有规格参数模板
        }
      }
    }
</script>

<style scoped>
  @-moz-keyframes loader {
    from {
      transform: rotate(0);
    }
    to {
      transform: rotate(360deg);
    }
  }
  @-webkit-keyframes loader {
    from {
      transform: rotate(0);
    }
    to {
      transform: rotate(360deg);
    }
  }
  @-o-keyframes loader {
    from {
      transform: rotate(0);
    }
    to {
      transform: rotate(360deg);
    }
  }
  @keyframes loader {
    from {
      transform: rotate(0);
    }
    to {
      transform: rotate(360deg);
    }
  }
</style>
